package cn.com.cifi.mars.web.action.common;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import cn.com.cifi.mars.bean.vo.monitoringConsole.PortalTodoVo;
import cn.com.cifi.mars.bean.vo.price.PriceApproveWarnConfirmTodoVO;
import cn.com.cifi.mars.bean.vo.price.PriceApproveWarnTodoVO;
import cn.com.cifi.mars.bean.vo.sys.rsp.CommonProjectByStagesVo;
import cn.com.cifi.mars.bean.vo.sys.rsp.GroupUserVo;
import cn.com.cifi.mars.common.base.BaseAction;
import cn.com.cifi.mars.common.bean.R;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.common.redis.RedisTemplateUtil;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.StageStatusEnum;
import cn.com.cifi.mars.constant.WhetherEnum;
import cn.com.cifi.mars.entity.MdmStage;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.service.ApprovalBillService;
import cn.com.cifi.mars.service.ApprovalWarningService;
import cn.com.cifi.mars.service.ApprovalWarningSuperviseService;
import cn.com.cifi.mars.service.BudgetLockRecordService;
import cn.com.cifi.mars.service.BudgetVersionIdentifyService;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.IdmUserService;
import cn.com.cifi.mars.service.PriceApprovalCoreWarnService;
import cn.com.cifi.mars.service.PriceApprovalDifferencesBuildService;
import cn.com.cifi.mars.service.PriceApprovalDifferencesDetailService;
import cn.com.cifi.mars.service.PriceApprovalDifferencesService;
import cn.com.cifi.mars.service.StageService;
import cn.com.cifi.mars.service.SupplyPlanVersionService;
import cn.com.cifi.mars.service.SysLogService;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class CommonController extends BaseAction implements ICommonController {

    @Value("${cifi.application.mappingPath}")
    private String physicalPath;
    @Autowired
    private CommonService commonService;
    @Autowired
    private IdmUserService idmUserService;
    @Autowired
	private SysLogService sysLogService;
    @Autowired
	private RedisTemplateUtil redisTemplateUtil;
    @Autowired
	private SupplyPlanVersionService supplyPlanVersionService;
    @Autowired
    private ApprovalBillService businessOAIntegratedService;
    @Autowired
    private ApprovalWarningService approvalWarningService;
    @Autowired
	private BudgetVersionIdentifyService budgetVersionIdentifyService;
    @Autowired
	private BudgetLockRecordService budgetLockRecordService;
    @Autowired
    private StageService stageService;
    @Autowired
    private ApprovalWarningSuperviseService approvalWarningSuperviseService;
    @Autowired
    private PriceApprovalCoreWarnService priceApprovalCoreWarnService;
    @Autowired
    private PriceApprovalDifferencesService priceApprovalDifferencesService;
    @Autowired
    private PriceApprovalDifferencesDetailService priceApprovalDifferencesDetailService;
    @Autowired
    private PriceApprovalDifferencesBuildService priceApprovalDifferencesBuildService;
    
    @Override
    public R uploadFiles(String apiVersion, MultipartFile file) {
        File dir;
        String extensionName = "";
        String originalFilename = file.getOriginalFilename();
        if (originalFilename != null && !"".equals(originalFilename)) {
            int index = originalFilename.lastIndexOf(".");
            if (index > 0) {
                extensionName = originalFilename.substring(index, originalFilename.length());
            }
        }
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;

        String ypath = physicalPath + "/" + year;
        String mpath = physicalPath + "/" + year + "/" + month;
        //检查目录是否存在，存在就直接使用，不存在就创建目录
        dir = new File(ypath);
        if (!dir.exists()) {
            dir = new File(mpath);
            dir.mkdirs();
        } else {
            dir = new File(mpath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }
        //获取一个UUID来作为存入服务器中的文件的名字
        String filename = UUIDUtils.create();
        filename = filename + extensionName;
        try {
            //将文件转存到指定位置
            file.transferTo(new File(dir, filename));
        } catch (Exception e) {
            log.error("###### errorMsg: ", e);
        }
        //将文件的服务器地址存到数据库
        String path = "/" + year + "/" + month + "/" + filename;
        return ok(path);
    }
    
    /**
	 * 根据组织机构id查询组织机构信息
	 */
	@Override
	public R<CommonProjectByStagesVo> getOrgList(String apiVersion, String regionId, String cityId,String projectId) {
		return ok(commonService.getOrgList(regionId,cityId,projectId));
	}
	
	/**
	  * 根据组织机构id和岗位组id查询所对应的用户信息
	 */
	@Override
	public R<HashSet<GroupUserVo>> getGroupUserList(String apiVersion, String groupId, String orgdepId) {
		return ok(idmUserService.getGroupUserInfo(groupId, orgdepId));
	}

	@Override
	public R<List<PortalTodoVo>> getPcToDo(String apiVersion, String todoTypeCode, String projectId,String instanceId) {
		return ok(commonService.getToDoInfo(todoTypeCode,projectId,instanceId));
	}

	@Override
	public R<List<PortalTodoVo>> getAppToDo(String apiVersion, String todoTypeCode, String projectId,String instanceId) {
		return ok(commonService.getToDoInfo(todoTypeCode,projectId,instanceId));
	}

	@Override
	public R<String> updatePortalProcess(String apiVersion, String instanceId, String operatorType) {
		IdmUser user = getOperator();
		return ok(commonService.updatePortalProcess(instanceId, operatorType, user, user));
	}
	
	@Override
	public R cleanPcToDo(String apiVersion, String todoTypeCode, String operatorType, String projectId,String instanceId) {
		IdmUser user = getOperator();
		commonService.cleanTodo(todoTypeCode,operatorType,projectId,instanceId,user);
		return ok();
	}

	@Override
	public R cleanAppToDo(String apiVersion, String todoTypeCode, String operatorType, String projectId,String instanceId) {
		IdmUser user = getOperator();
		commonService.cleanTodo(todoTypeCode,operatorType,projectId,instanceId,user);
		return ok();
	}

	@Override
	public R cleanSysLog(String apiVersion, int day) {
		sysLogService.deleteLog(day);
		return ok();
	}

	@Override
	public R cleanRedisKey(String apiVersion, String key) {
		if(redisTemplateUtil.get(key) != null) {
			redisTemplateUtil.delete(key);
		}else {
			return ok("key值不存在："+key);
		}
		return ok();
	}

    @Override
    public R getRedisKey(String apiVersion, String key) {
        Object data = redisTemplateUtil.get(key);
        if(data != null) {
            return ok(data.toString());
        }else {
            return ok("key值不存在："+key);
        }
    }

	@Override
	public R supplyConfirmYearMonth(String apiVersion, String yearMonth) {
		String affiliationMonth = "";
		String showMonth = "";
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		if(LocalDateTimeUtils.isSameMonth(yearMonth)) {
			affiliationMonth = supplyPlanVersionService.getAffiliationMonth(yearMonth);
			LocalDateTime now = LocalDateTime.now();
			String comfirmTime  = supplyPlanVersionService.getComfirmTime();
			LocalDateTime endComfirmTime = LocalDateTimeUtils.strToDate(comfirmTime, df);
			LocalDateTime beginTimeTemp = endComfirmTime.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
			LocalDateTime beginComfirmTime = beginTimeTemp.with(TemporalAdjusters.lastDayOfMonth()).minusDays(1);
			if(now.isBefore(beginComfirmTime)) {
				showMonth = LocalDateTimeUtils.getLastMonth(yearMonth);
			}else {
				showMonth = affiliationMonth;
			}
		}else {
			affiliationMonth = yearMonth;
			showMonth = LocalDateTimeUtils.getLastMonth(yearMonth);
		}
		LocalDateTime time = LocalDateTimeUtils.parseDate(showMonth+"-01 00:00:00",df);
    	int monthNum = time.getMonthValue();
    	int year = time.getYear();
    	//详情页面展示的月份
    	List<String> months = LocalDateTimeUtils.getSupplyConfirmDetailMonths(year,monthNum);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("affiliationMonth", affiliationMonth);
		map.put("showMonth", showMonth);
		map.put("months", months);
		return ok(map);
	}
	
	@Override
	public String getToken(String apiVersion, String requestParam) {
		return businessOAIntegratedService.getAuthToken();
	}

	@Override
	public String saveFlow(String apiVersion, String sessionToken, String requestParam) {
		return businessOAIntegratedService.saveFlow(sessionToken, requestParam);
	}

	@Override
	public String endFlow(String apiVersion, String sessionToken, String requestParam) {
		return businessOAIntegratedService.endFlow(sessionToken, requestParam);
	}

	@Override
	public String deleteFlow(String apiVersion, String sessionToken, String requestParam) {
		return businessOAIntegratedService.deleteFlow(sessionToken, requestParam);
	}

	@Override
	public String selectFlowOpinions(String apiVersion, String sessionToken, String requestParam) {
		return businessOAIntegratedService.selectFlowOpt(sessionToken, requestParam);
	}

	@Override
	public String selectFlowPath(String apiVersion, String sessionToken, String requestParam) {
		return businessOAIntegratedService.selectFlowPath(sessionToken, requestParam);
	}

	@Override
	public R getWarnPcToDo(String apiVersion, String instanceId) {
		PriceApproveWarnTodoVO vo = approvalWarningService.getPriceApproveWarnTodo(instanceId);
		return ok(vo);
	}

	@Override
	public R getWarnSupervisePcToDo(String apiVersion, String instanceId,String userId) {
		IdmUser user = getOperator();
		PriceApproveWarnConfirmTodoVO vo = approvalWarningService.getPriceApproveWarnConfirmTodo(user,instanceId,userId);
		return ok(vo);
	}

	@Override
	public R sendWarnSupervise(String apiVersion, String instanceId) {
		IdmUser user = getOperator();
		approvalWarningService.sendWarnSupervise(user,instanceId);
		return ok();
	}

	@Override
	public R budgetVersion(String apiVersion) {
		String version = budgetVersionIdentifyService.getVersion();
		return ok(version);
	}

	@Override
	public R createBudgetVerify(String apiVersion, String projectId,String stageId, String type) {
		String versionIdentify = budgetVersionIdentifyService.getVersion();
		//1、项目锁定不允许
		Integer lockStatus = budgetLockRecordService.getLockStatus(projectId,type);
		if(lockStatus != null && lockStatus.intValue() == WhetherEnum.YES.getKey()) {
			throw new MsgException(CodeEnum.VERSION_IS_LOCK);
		}
		//2、分期已存在定稿版不允许
		boolean isExistFinalVersion = budgetLockRecordService.isExistFinalVersion(stageId,type,versionIdentify);
		if(isExistFinalVersion) {
			throw new MsgException(CodeEnum.VERSION_EXIST_FINAL_NOT);
		}
		//3、分期禁用不允许
  		MdmStage mdmStage = stageService.selectById(stageId);
  		if(mdmStage != null && StrUtils.isNotEmpty(mdmStage.getStatus()) && mdmStage.getStatus().equals(StageStatusEnum.INACTIVE.getKey())) {
  			 throw new MsgException(CodeEnum.CREATE_INACTIVE_STAGE_ERROR);
  		}
		return ok();
	}

	@Override
	public R warningSuperviseTest(String apiVersion, String billId, Integer eventType) {
		approvalWarningSuperviseService.sendWarningSupervise(billId,eventType);
		return ok();
	}

	@Override
	public R savePriceExcelData(String apiVersion, String billId, String versionState, String projectId) {
		//保存货值审批全盘概览数据
		priceApprovalDifferencesService.saveData(billId);
		//保存货值审批全盘差异详情数据
		priceApprovalDifferencesDetailService.saveData(billId,projectId,versionState);
		//保存货值审批本次调价楼栋数据
		priceApprovalDifferencesBuildService.savePriceApprovalDifferencesBuildData(billId,projectId,versionState);
		//保存货值审批核心指标数据
		priceApprovalCoreWarnService.savePriceApprovalCoreWarnData(billId,projectId,versionState);
		return ok();
	}

	@Override
	public R handleData(String apiVersion,String strInfo) {
		sysLogService.handleData(strInfo);
		return ok();
	}
	
}
